﻿/*
  Copyright © Alexander G. Bykin, Russia 2010
  This source is subject to the Microsoft Public License (Ms-PL).
  Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
  Project link: http://datagridriaex4sl.codeplex.com/
  Related project link: http://riadatafilter.codeplex.com/
  All other rights reserved.
*/

namespace DataGridRIAExtension
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.Linq;
    using System.Reflection;
    using System.ServiceModel.DomainServices.Client;
    using System.Windows.Data;

    public class RIAExtensionConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            string result = string.Empty;
            DomainContext domainContext = value as DomainContext;
            string entityPropertyPath = System.Convert.ToString(parameter);
            string entityType = string.Empty;
            string entityTypePropertyPath = string.Empty;
            List<Type> entityTypeList = new List<Type>();
            IDictionary<string, BindingMode> bindingModes = new Dictionary<string, BindingMode>();

            if (domainContext == null)
            {
                if (System.Diagnostics.Debugger.IsAttached)
                {
                    System.Diagnostics.Debug.WriteLine("Value must be set to DomainContext");
                }
                return result;
            }

            entityTypeList = Utilities.GetListOfEntityTypeFromDomainContext(domainContext);

            string[] tmpValues = entityPropertyPath.Split('.');
            if (string.IsNullOrWhiteSpace(entityPropertyPath) || !entityPropertyPath.Contains('.') || tmpValues.Length != 2 || string.IsNullOrWhiteSpace(tmpValues[0]) || string.IsNullOrWhiteSpace(tmpValues[1]))
            {
                if (System.Diagnostics.Debugger.IsAttached)
                {
                    System.Diagnostics.Debug.WriteLine("PropertyPath can not be null and must have format 'EntityType.PropertyPath'");
                }
                return result;
            }

            entityType = tmpValues[0];
            entityTypePropertyPath = tmpValues[1];

            bool IsEntityFound = false;
            bool IsPropertyPathFound = false;
            foreach (Type entityItem in entityTypeList)
            {
                if (entityItem.Name.ToLower() == entityType.ToLower())
                {
                    IsEntityFound = true;
                    if (System.Diagnostics.Debugger.IsAttached)
                    {
                        System.Diagnostics.Debug.WriteLine(string.Format("EntityType '{0}' is found", entityType));
                    }

                    foreach (PropertyInfo propertyPathItem in entityItem.GetEntityProperties())
                    {
                        if (propertyPathItem.Name.ToLower() == entityTypePropertyPath.ToLower())
                        {
                            DisplayAttribute displayAttribute = Utilities.GetPropertyDisplayAttribute(entityItem.Name, propertyPathItem, bindingModes);

                            string displayName = string.Empty;
                            string propertyPath = string.Empty;

                            Utilities.GetEntityFieldInfo(propertyPathItem, displayAttribute, out displayName, out propertyPath);
                            result = displayName;
                            IsPropertyPathFound = true;
                            if (System.Diagnostics.Debugger.IsAttached)
                            {
                                System.Diagnostics.Debug.WriteLine(string.Format("PropertyPath '{0}' is found", entityTypePropertyPath));
                            }
                            break;
                        }
                    }

                    if (!IsPropertyPathFound)
                    {
                        if (System.Diagnostics.Debugger.IsAttached)
                        {
                            System.Diagnostics.Debug.WriteLine(string.Format("PropertyPath '{0}' is not found at EntityType '{1}'", entityTypePropertyPath, entityType));
                        }
                    }

                    break;
                }
            }

            if (!IsEntityFound)
            {
                if (System.Diagnostics.Debugger.IsAttached)
                {
                    System.Diagnostics.Debug.WriteLine(string.Format("EntityType '{0}' is not found at DomainContext", entityType));
                }
            }

            return result;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return value;
        }
    }
}
